package com.hnas.eCard.dao.impl;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.Query;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;

import com.hnas.core.dao.BaseDaoImpl;
import com.hnas.core.util.StringUtil;
import com.hnas.eCard.dao.EntityCardOrderDetailDao;
import com.hnas.eCard.domain.ECardCommonFinalValue;
import com.hnas.eCard.orm.EntityCardOrderDetail;
import com.hnas.eCard.orm.EntityDenominationRe;
import com.hnas.eCard.service.dto.DTOEntityCardOrder;
import com.hnas.eCard.service.dto.DTOEntityCardOrderDetail;
import com.hnas.eCard.service.dto.DTOEntityCardRecord;

@Component("entityCardOrderDetailDao")
public class EntityCardOrderDetailDaoImpl extends BaseDaoImpl<EntityCardOrderDetail> implements EntityCardOrderDetailDao {

	public EntityCardOrderDetailDaoImpl() {
		super(EntityCardOrderDetail.class);
	}

	@Override
	public EntityCardOrderDetail saveOrUpdate(DTOEntityCardOrderDetail dto) {
		EntityCardOrderDetail vo = null;
		try {
			if(dto != null){
				String id = dto.getId();
				if(StringUtil.isNotEmpty(id)){
					vo = this.find(id);
				}	
				if(vo == null){//新增
					vo = new EntityCardOrderDetail();
					BeanUtils.copyProperties(dto, vo);
					this.persist(vo);
				}else{//修改
					BeanUtils.copyProperties(dto, vo);
					this.merge(vo);
				}
			}
			return vo;
		} catch (Exception e) {
			e.printStackTrace();
			return vo;
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public EntityCardOrderDetail findByOrderNo(String orderNo) {
		if(StringUtil.isEmpty(orderNo)) return null;
		String hql = "from EntityCardOrderDetail t where t.orderNo = ?1";
		Query query = this.entityManager.createQuery(hql);
		query.setParameter(1, orderNo);
		List<EntityCardOrderDetail> resultList = query.getResultList();
		if(resultList != null && resultList.size() > 0) {
			return resultList.get(0);
		}
		return null;
	}

	@Override
	public DTOEntityCardOrder findEntityCardOrderByOrderNo(String orderNo) {
		if(StringUtil.isEmpty(orderNo)) return null;
		StringBuilder sb = queryOrderSql();
		sb.append(" from m_base_wxxnk_order t1 left join tbl_entity_card_order_detail t2 on t1.order_no = t2.order_no where t1.order_no = ?1");
		Query query = this.entityManager.createNativeQuery(sb.toString());
		query.setParameter(1, orderNo);
		List<Object[]> resultList = query.getResultList();
		if(resultList != null && resultList.size() > 0) {
			Object[] result = resultList.get(0);
			DTOEntityCardOrder dto = assembleDTOEntityCardOrder(result);
			return dto;
		}
		return null;
	}

	@Override
	public DTOEntityCardOrder findEntityCardOrderBySwiftNumber(String swiftNumber) {
		if(StringUtil.isEmpty(swiftNumber)) return null;
		StringBuilder sb = queryOrderSql();
		sb.append(" from m_base_wxxnk_order t1 left join tbl_entity_card_order_detail t2 on t1.order_no = t2.order_no where t1.swift_number = ?1");
		Query query = this.entityManager.createNativeQuery(sb.toString());
		query.setParameter(1, swiftNumber);
		List<Object[]> resultList = query.getResultList();
		if(resultList != null && resultList.size() > 0) {
			Object[] result = resultList.get(0);
			DTOEntityCardOrder dto = assembleDTOEntityCardOrder(result);
			return dto;
		}
		return null;
	}
	
	private DTOEntityCardOrder assembleDTOCommoditOrder(Object[] result) {
		DTOEntityCardOrder dto = new DTOEntityCardOrder();
		dto.setId(String.valueOf(result[0]));
		dto.setOrderNo(String.valueOf(result[1]));
		dto.setOrderType(String.valueOf(result[2]));
		dto.setOrderTypeName(String.valueOf(result[3]));
		dto.setAccId(String.valueOf(result[4]));
		dto.setAccName(String.valueOf(result[5]));
		dto.setOrderDetail(String.valueOf(result[6]));
		dto.setOrderStatus(String.valueOf(result[7]));
		dto.setPayment(String.valueOf(result[8]));
		dto.setPayStatus(String.valueOf(result[9]));
		dto.setNeedPay(((BigInteger)result[10]).longValue());
		dto.setRealPay(((BigInteger)result[11]).longValue());
		dto.setTradeType(String.valueOf(result[12]));
		dto.setSwiftNumber(String.valueOf(result[13]));
		dto.setCommidityId(String.valueOf(result[14]));
		dto.setCommidityName(String.valueOf(result[15]));
		dto.setCommidityType(String.valueOf(result[16]));
		dto.setCardNo(String.valueOf(result[17]));
		dto.setMrchId(String.valueOf(result[18]));
		dto.setMrchName(String.valueOf(result[19]));
		dto.setMrchType(String.valueOf(result[20]));
		dto.setPsamId(String.valueOf(result[21]));
		dto.setSubId(String.valueOf(result[22]));
		dto.setTradeSno(String.valueOf(result[23]));
		dto.setTradeEndTime(String.valueOf(result[24]));
		dto.setPayEndTime(String.valueOf(result[25]));
		dto.setCancelTime(String.valueOf(result[26]));
		dto.setCreateTime(String.valueOf(result[27]));
		dto.setUpdateTime(String.valueOf(result[28]));
		dto.setCreator(String.valueOf(result[29]));
		dto.setUpdater(String.valueOf(result[30]));
		dto.setIsDeleted((Boolean)result[31]);
		dto.setRemark(String.valueOf(result[32]));
		dto.setOrderParentType(String.valueOf(result[33]));
		dto.setTermNo(String.valueOf(result[34]));
		dto.setEntityStatus(Integer.valueOf(String.valueOf(result[35])));
		dto.setAddress(String.valueOf(result[36]));
		return dto;
	}
	
	private DTOEntityCardRecord assembleDTOEntityCardRecord(Object[] result) {
		DTOEntityCardRecord dto = new DTOEntityCardRecord();
		dto.setId(String.valueOf(result[0]));
		dto.setOrderNo(String.valueOf(result[1]));
		dto.setOrderType(String.valueOf(result[2]));
		dto.setOrderTypeName(String.valueOf(result[3]));
		dto.setAccId(String.valueOf(result[4]));
		dto.setAccName(String.valueOf(result[5]));
		dto.setOrderDetail(String.valueOf(result[6]));
		dto.setOrderStatus(String.valueOf(result[7]));
		dto.setPayment(String.valueOf(result[8]));
		dto.setNeedPay(((BigDecimal)result[9]).longValue());
		dto.setRealPay(((BigDecimal)result[10]).longValue());
		dto.setTradeType(String.valueOf(result[11]));
		dto.setSwiftNumber(String.valueOf(result[12]));
		dto.setCommidityId(String.valueOf(result[13]));
		dto.setCommidityName(String.valueOf(result[14]));
		dto.setCommidityType(String.valueOf(result[15]));
		dto.setCardNo(String.valueOf(result[16]));
		dto.setMrchId(String.valueOf(result[17]));
		dto.setMrchName(String.valueOf(result[18]));
		dto.setMrchType(String.valueOf(result[19]));
		dto.setPsamId(String.valueOf(result[20]));
		dto.setSubId(String.valueOf(result[21]));
		dto.setTradeSno(String.valueOf(result[22]));
		dto.setTradeEndTime(String.valueOf(result[23]));
		dto.setPayEndTime(String.valueOf(result[24]));
		dto.setCreateTime(String.valueOf(result[25]));
		dto.setUpdateTime(String.valueOf(result[26]));
		dto.setIsDeleted(((Boolean)result[27]));
		dto.setRemark(String.valueOf(result[28]));
		dto.setOrderParentType(String.valueOf(result[29]));
		dto.setTermNo(String.valueOf(result[30]));
		dto.setEntityStatus(((Integer)result[33]).intValue());
		return dto;
	}
	
	private DTOEntityCardOrder assembleDTOEntityCardOrder(Object[] result) {
		DTOEntityCardOrder dto = new DTOEntityCardOrder();
		dto.setId(String.valueOf(result[0]));
		dto.setOrderNo(String.valueOf(result[1]));
		dto.setOrderType(String.valueOf(result[2]));
		dto.setOrderTypeName(String.valueOf(result[3]));
		dto.setAccId(String.valueOf(result[4]));
		dto.setAccName(String.valueOf(result[5]));
		dto.setOrderDetail(String.valueOf(result[6]));
		dto.setOrderStatus(String.valueOf(result[7]));
		dto.setPayment(String.valueOf(result[8]));
		dto.setPayStatus(String.valueOf(result[9]));
		dto.setNeedPay(((BigInteger)result[10]).longValue());
		dto.setRealPay(((BigInteger)result[11]).longValue());
		dto.setTradeType(String.valueOf(result[12]));
		dto.setSwiftNumber(String.valueOf(result[13]));
		dto.setCommidityId(String.valueOf(result[14]));
		dto.setCommidityName(String.valueOf(result[15]));
		dto.setCommidityType(String.valueOf(result[16]));
		dto.setCardNo(String.valueOf(result[17]));
		dto.setMrchId(String.valueOf(result[18]));
		dto.setMrchName(String.valueOf(result[19]));
		dto.setMrchType(String.valueOf(result[20]));
		dto.setPsamId(String.valueOf(result[21]));
		dto.setSubId(String.valueOf(result[22]));
		dto.setTradeSno(String.valueOf(result[23]));
		dto.setTradeEndTime(String.valueOf(result[24]));
		dto.setPayEndTime(String.valueOf(result[25]));
		dto.setCancelTime(String.valueOf(result[26]));
		dto.setCreateTime(String.valueOf(result[27]));
		dto.setUpdateTime(String.valueOf(result[28]));
		dto.setCreator(String.valueOf(result[29]));
		dto.setUpdater(String.valueOf(result[30]));
		dto.setIsDeleted((Boolean)result[31]);
		dto.setRemark(String.valueOf(result[32]));
		dto.setOrderParentType(String.valueOf(result[33]));
		dto.setTermNo(String.valueOf(result[34]));
		dto.setEntityStatus(((Integer)result[35]).intValue());
		return dto;
	}

	private StringBuilder queryOrderSql() {
		StringBuilder sb = new StringBuilder();
		sb.append("select t1.id,")
		.append("t1.order_no,")
		.append("t1.order_type,")
		.append("t1.order_type_name,")
		.append("t1.acc_id,")
		.append("t1.acc_name,")
		.append("t1.order_detail,")
		.append("t1.order_status,")
		.append("t1.payment,")
		.append("t1.pay_status,")
		.append("t1.need_pay,")
		.append("t1.real_pay,")
		.append("t1.trade_type,")
		.append("t1.swift_number,")
		.append("t1.commidity_id,")
		.append("t1.commidity_type,")
		.append("t1.commidity_name,")
		.append("t1.card_no,")
		.append("t1.mrch_id,")
		.append("t1.mrch_name,")
		.append("t1.mrch_type,")
		.append("t1.psam_id,")
		.append("t1.sub_id,")
		.append("t1.trade_sno,")
		.append("t1.trade_end_time,")
		.append("t1.pay_end_time,")
		.append("t1.cancel_time,")
		.append("t1.create_time,")
		.append("t1.update_time,")
		.append("t1.creator,")
		.append("t1.updater,")
		.append("t1.is_deleted,")
		.append("t1.remark,")
		.append("t1.order_parent_type,")
		.append("t1.term_no,")
		.append("t2.entity_status");
		return sb;
	}
	
	private StringBuilder queryCommoditOrderSql() {
		StringBuilder sb = new StringBuilder();
		sb.append("select distinct(t1.id),")
		.append("t1.order_no,")
		.append("t1.order_type,")
		.append("t1.order_type_name,")
		.append("t1.acc_id,")
		.append("t1.acc_name,")
		.append("t1.order_detail,")
		.append("t1.order_status,")
		.append("t1.payment,")
		.append("t1.pay_status,")
		.append("t1.need_pay,")
		.append("t1.real_pay,")
		.append("t1.trade_type,")
		.append("t1.swift_number,")
		.append("t1.commidity_id,")
		.append("t1.commidity_type,")
		.append("t1.commidity_name,")
		.append("t1.card_no,")
		.append("t1.mrch_id,")
		.append("t3.mrch_name,")
		.append("t1.mrch_type,")
		.append("t1.psam_id,")
		.append("t1.sub_id,")
		.append("t1.trade_sno,")
		.append("t1.trade_end_time,")
		.append("t1.pay_end_time,")
		.append("t1.cancel_time,")
		.append("t1.create_time,")
		.append("t1.update_time,")
		.append("t1.creator,")
		.append("t1.updater,")
		.append("t1.is_deleted,")
		.append("t1.remark,")
		.append("t1.order_parent_type,")
		.append("t1.term_no,")
		.append("t2.state,")
		.append("t3.address");
		return sb;
	}
	
	private StringBuilder queryRecordSql() {
		StringBuilder sb = new StringBuilder();
		sb.append("select t1.id,")
		.append("t1.order_no,")
		.append("t1.order_type,")
		.append("t1.order_type_name,")
		.append("t1.acc_id,")
		.append("t1.acc_name,")
		.append("t1.order_detail,")
		.append("t2.order_status,")
		.append("t1.payment,")
		.append("t1.need_pay,")
		.append("t1.real_pay,")
		.append("t1.trade_type,")
		.append("t1.swift_number,")
		.append("t1.commidity_id,")
		.append("t1.commidity_type,")
		.append("t1.commidity_name,")
		.append("t1.card_no,")
		.append("t1.mrch_id,")
		.append("t1.mrch_name,")
		.append("t1.mrch_type,")
		.append("t1.psam_id,")
		.append("t1.sub_id,")
		.append("t1.trade_sno,")
		.append("t1.trade_end_time,")
		.append("t1.pay_end_time,")
		.append("t1.create_time,")
		.append("t1.update_time,")
		.append("t1.creator,")
		.append("t1.updater,")
		.append("t1.is_deleted,")
		.append("t1.remark,")
		.append("t1.order_parent_type,")
		.append("t1.term_no,")
		.append("t2.entity_status");
		return sb;
	}

	@Override
	public DTOEntityCardRecord findEntityCardRecordBySwiftNumber(String swiftNumber) {
		if(StringUtil.isEmpty(swiftNumber)) return null;
		StringBuilder sb = queryRecordSql();
		sb.append(" from m_base_wxxnk_trade_record t1 left join tbl_entity_card_order_detail t2 on t1.order_no = t2.order_no where t1.swift_number = ?1");
		Query query = this.entityManager.createNativeQuery(sb.toString());
		query.setParameter(1, swiftNumber);
		List<Object[]> resultList = query.getResultList();
		if(resultList != null && resultList.size() > 0) {
			Object[] result = resultList.get(0);
			DTOEntityCardRecord dto = assembleDTOEntityCardRecord(result);
			return dto;
		}
		return null;
	}

	@Override
	public List<DTOEntityCardOrder> findEntityOrderListByAccId(String accId) {
		if(StringUtil.isEmpty(accId)) return null;
		StringBuilder sb = queryOrderSql();
		sb.append(" from m_base_wxxnk_order t1,tbl_entity_card_order_detail t2 where t1.order_no = t2.order_no and t1.acc_id = ?1 order by t1.create_time desc");
		Query query = this.entityManager.createNativeQuery(sb.toString());
		query.setParameter(1, accId);
		List<Object[]> resultList = query.getResultList();
		if(resultList != null && resultList.size() > 0) {
			List<DTOEntityCardOrder> list = new ArrayList<DTOEntityCardOrder>();
			for(Object[] result:resultList) {
				DTOEntityCardOrder dto = assembleDTOEntityCardOrder(result);
				String sql = "select * from tbl_entity_denomination_re where order_no = ?1 order by denomination asc";
				Query query2 = this.entityManager.createNativeQuery(sql,EntityDenominationRe.class);
				query2.setParameter(1, dto.getOrderNo());
				List resultList2 = query2.getResultList();
				dto.setDenominationList(resultList2);
				list.add(dto);
			}
			return list;
		}
		return null;
	}

	@Override
	public boolean confirmConsume(String accId, String orderNo,String mrchId,String termNo,String dealDate) {
		String sql = "update tbl_entity_card_order_detail set entity_status = ?1,mrch_id=?2,term_no=?3,update_time=?4 where order_no = ?5 and entity_status=?6";
		Query query = this.entityManager.createNativeQuery(sql);
		query.setParameter(1, ECardCommonFinalValue.ENTITY_CARD_ORDER_USED);
		query.setParameter(2, mrchId);
		query.setParameter(3, termNo);
		query.setParameter(4, dealDate);
		query.setParameter(5, orderNo);
		query.setParameter(6, ECardCommonFinalValue.ENTITY_CARD_ORDER_UNUSE);
		int ret = query.executeUpdate();
		return ret==1?true:false;
	}

	@Override
	public DTOEntityCardOrder getEntityByOrderNo(String orderNo) {
		if(StringUtil.isEmpty(orderNo)) return null;
		StringBuilder sb = queryOrderSql();
		sb.append(" from m_base_wxxnk_order t1 left join tbl_entity_card_order_detail t2 on t1.order_no = t2.order_no where t1.order_no = ?1");
		Query query = this.entityManager.createNativeQuery(sb.toString());
		query.setParameter(1, orderNo);
		List<Object[]> resultList = query.getResultList();
		if(resultList != null && resultList.size() > 0) {
			Object[] result = resultList.get(0);
			DTOEntityCardOrder dto = assembleDTOEntityCardOrder(result);
			String sql = "select * from tbl_entity_denomination_re where order_no = ?1 order by denomination asc";
			Query query2 = this.entityManager.createNativeQuery(sql,EntityDenominationRe.class);
			query2.setParameter(1, orderNo);
			List resultList2 = query2.getResultList();
			dto.setDenominationList(resultList2);
			return dto;
		}
		return null;
	}
	
	@Override
	public DTOEntityCardOrder getCommoditByOrderNo(String orderNo) {
		if(StringUtil.isEmpty(orderNo)) return null;
		StringBuilder sb = queryCommoditOrderSql();
		sb.append(" from m_base_wxxnk_order t1,tbl_commodit_order_detail t2,tbl_commodit_mrch t3,tbl_commodit t4,tbl_commodit_detail_re t5 where t1.order_no = t2.order_no and t5.commodit_id = t4.id and t4.mrch_id = t3.mrch_id and t5.order_no = t1.order_no and t1.order_no = ?1");
		Query query = this.entityManager.createNativeQuery(sb.toString());
		query.setParameter(1, orderNo);
		List<Object[]> resultList = query.getResultList();
		if(resultList != null && resultList.size() > 0) {
			Object[] result = resultList.get(0);
			DTOEntityCardOrder dto = assembleDTOCommoditOrder(result);
			return dto;
		}
		return null;
	}

}
